package com.link.base.tencent.corpwx.externalcontact.service;

import javax.annotation.Resource;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.link.base.tencent.corpwx.agent.service.AgentService;
import com.link.base.tencent.corpwx.agent.util.AgentIdUtil;
import com.link.base.tencent.corpwx.externalcontact.dao.mybatis.mapper.GroupChatUserMapper;
import com.link.base.tencent.corpwx.externalcontact.model.GroupChatUser;
import com.link.base.tencent.corpwx.externalcontact.util.ExternalContactUtil;
import com.link.core.basic.service.KeyGenerateService;
import com.link.core.util.DateUtil;
import org.springframework.stereotype.Service;
import com.link.base.tencent.corpwx.externalcontact.dao.mybatis.mapper.GroupChatMapper;
import com.link.base.tencent.corpwx.externalcontact.model.GroupChat;
import com.link.core.basic.dao.mapper.BasicMapper;
import com.link.core.basic.service.BasicServiceImpl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 客户群管理 
 *
 * @author 欧阳振强
 * @date 2020-03-18 15:08:43.0
 */
@Service
public class GroupChatServiceImpl extends BasicServiceImpl<GroupChat> implements GroupChatService {

    @Resource
    private AgentService agentService;
    @Resource
    private KeyGenerateService keyGenerateService;
    @Resource
    private GroupChatUserMapper groupChatUserMapper;
    @Resource
    private GroupChatMapper groupChatMapper;
    
    @Override
    public BasicMapper<GroupChat> getBasicMapper() {
        return groupChatMapper;
    }

    @Override
    public void syncGroupChatFromWx() throws Exception {
        String accessToken = agentService.getExistAccessToken(AgentIdUtil.CORPWX_ACCOUNT_AGENTID);
        // 每页查询结果的群聊总数
        int pageTotal = 500;
        // 默认分页基数
        int limit = 500;
        // 偏移量
        int offset = 0;
        // 获取客户群列表 - 普通列表，如果当前页总数和分页基数相等，则尝试查询下一页，默认设置为相等，触发第一次查询
        while (pageTotal == limit) {
            List<GroupChat> groupChats = new ArrayList<>();
            JSONObject result = ExternalContactUtil.getGroupChatList(accessToken, null, null,
                    "0", String.valueOf(offset), String.valueOf(limit));
            JSONArray groupChatList = result.getJSONArray("group_chat_list");
            pageTotal = groupChatList.size();
            offset = pageTotal;
            JSONObject groupChatItem;
            GroupChat groupChat;
            for (int i = 0; i < pageTotal; i++) {
                groupChatItem = groupChatList.getJSONObject(i);
                groupChat = new GroupChat();
                String chatId = groupChatItem.getString("chat_id");
                groupChat.setChatId(chatId);
                groupChat.setChatStatus(groupChatItem.getString("status"));
                // 获取群聊详情
                accessToken = agentService.getExistAccessToken(AgentIdUtil.CORPWX_ACCOUNT_AGENTID);
                JSONObject groupChatResult = ExternalContactUtil.getGroupChatInfoById(accessToken, chatId);
                JSONObject groupChatInfo = groupChatResult.getJSONObject("group_chat");
                groupChat.setChatName(groupChatInfo.getString("name"));
                groupChat.setChatOwner(groupChatInfo.getString("owner"));
                groupChat.setNotice(groupChatInfo.getString("notice"));
                groupChat.setCreateTime(DateUtil.dateToStr(
                        new Date(groupChatInfo.getLong("create_time") * 1000), "yyyy-MM-dd HH:mm:ss"));
                // 解析群聊成员
                JSONArray memberListObj = groupChatInfo.getJSONArray("member_list");
                List<GroupChatUser> groupChatUserList = new ArrayList<>();
                GroupChatUser groupChatUser;
                for (int j = 0, size = memberListObj.size(); j < size; j++) {
                    JSONObject memberItemObj = memberListObj.getJSONObject(j);
                    groupChatUser = new GroupChatUser();
                    groupChatUser.setUserId(memberItemObj.getString("userid"));
                    groupChatUser.setUserType(memberItemObj.getString("type"));
                    groupChatUser.setJoinScene(memberItemObj.getString("join_scene"));
                    groupChatUser.setJoinTime(DateUtil.dateToStr(
                            new Date(memberItemObj.getLong("join_time") * 1000), "yyyy-MM-dd HH:mm:ss"));
                    groupChatUserList.add(groupChatUser);
                }
                groupChat.setGroupChatUserList(groupChatUserList);
                groupChats.add(groupChat);
            }
            dealGroupChat(groupChats);
        }
    }

    /**
     * 处理群聊对象，与数据库进行比对，不存在则新建，存在则更新
     * 
     * @author 欧阳振强
     * @date 2020/03/18
     * @param groupChats 群聊对象列表
     */
    void dealGroupChat(List<GroupChat> groupChats) throws Exception {
        for (GroupChat groupChat: groupChats) {
            GroupChat existData = groupChatMapper.getGroupChatByChatId(groupChat);
            if (existData == null) {
                // 不存在则新建
                Long parentId = keyGenerateService.keyGenerate();
                groupChat.setId(parentId);
                groupChatMapper.insert(groupChat);
                for (GroupChatUser groupChatUser: groupChat.getGroupChatUserList()) {
                    groupChatUser.setId(keyGenerateService.keyGenerate());
                    groupChatUser.setParentId(parentId);
                    groupChatUserMapper.insert(groupChatUser);
                }
            } else {
                // 更新
                groupChat.setId(existData.getId());
                groupChatMapper.update(groupChat);
                // 比对群聊成员
                List<GroupChatUser> dealGroupChatUsers = new ArrayList<>();
                List<GroupChatUser> apiGroupChatUsers = groupChat.getGroupChatUserList();
                List<GroupChatUser> existGroupChatUsers = groupChatUserMapper.getGroupChatUserListByParentId(groupChat);
                Map<String, GroupChatUser> linkListMap =
                        existGroupChatUsers.stream().collect(Collectors.toMap(item -> item.getUserId(), item -> item));
                Map<String, GroupChatUser> apiListMap =
                        apiGroupChatUsers.stream().collect(Collectors.toMap(item -> item.getUserId(), item -> item));
                for (GroupChatUser linkItem: existGroupChatUsers) {
                    if (apiListMap.get(linkItem.getUserId()) == null) {
                        linkItem.setOpStatus("del");
                        dealGroupChatUsers.add(linkItem);
                    }
                }
                for (GroupChatUser apiItem: apiGroupChatUsers) {
                    if (linkListMap.get(apiItem.getUserId()) == null) {
                        apiItem.setOpStatus("add");
                        dealGroupChatUsers.add(apiItem);
                    }
                }
                for (GroupChatUser item: dealGroupChatUsers) {
                    if ("add".equals(item.getOpStatus())) {
                        item.setId(keyGenerateService.keyGenerate());
                        item.setParentId(existData.getId());
                        groupChatUserMapper.insert(item);
                    } else if ("del".equals(item.getOpStatus())) {
                        groupChatUserMapper.deleteById(item);
                    }
                }
            }
        }
    }
}
